package crp.services.api.graphql;

import crp.core.portal.app.PortalSectionService;
import crp.core.portal.domain.services.PortalSectionConfigBuilder;
import crp.core.security.domain.models.Permissions;
import crp.services.api.graphql.models.CreatePortalSectionInput;
import crp.services.api.graphql.models.DeletePortalSectionInput;
import crp.services.api.graphql.models.PortalSectionPayload;
import crp.services.api.graphql.models.UpdatePortalSectionInput;
import org.eclipse.microprofile.graphql.GraphQLApi;
import org.eclipse.microprofile.graphql.Mutation;
import org.eclipse.microprofile.graphql.Query;

import javax.annotation.security.PermitAll;
import javax.annotation.security.RolesAllowed;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.transaction.Transactional;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.stream.Collectors;

@GraphQLApi
@RequestScoped
@Transactional
public class PortalSectionGraphQLApi {
    private final PortalSectionService portalSectionService;
    private final PortalSectionConfigBuilder configBuilder;

    @Inject
    public PortalSectionGraphQLApi(PortalSectionService portalSectionService,
                                   PortalSectionConfigBuilder configBuilder) {
        this.portalSectionService = portalSectionService;
        this.configBuilder = configBuilder;
    }

    @Query
    @RolesAllowed(Permissions.PORTAL_SECTION_VIEW)
    @NotNull
    public List<@NotNull PortalSectionPayload> portalSections() {
        return portalSectionService.searcher().all()
                .map(PortalSectionPayload::of)
                .collect(Collectors.toList());
    }

    @Query
    @PermitAll
    @NotNull
    public List<@NotNull PortalSectionPayload> enabledPortalSections() {
        return portalSectionService.searcher().enabled()
                .map(PortalSectionPayload::of)
                .collect(Collectors.toList());
    }

    @Mutation
    @RolesAllowed(Permissions.PORTAL_SECTION_EDIT)
    @NotNull
    public PortalSectionPayload createPortalSection(@NotNull @Valid CreatePortalSectionInput input) {
        return PortalSectionPayload.of(portalSectionService.editor()
                .create(input.getName(),
                        configBuilder.build(input.getLoadStrategy(), input.getFixedCourseIds())));
    }

    @Mutation
    @RolesAllowed(Permissions.PORTAL_SECTION_EDIT)
    @NotNull
    public PortalSectionPayload updatePortalSection(@NotNull @Valid UpdatePortalSectionInput input) {
        return PortalSectionPayload.of(portalSectionService.editor()
                .update(input.getId(), input.getName(),
                        configBuilder.build(input.getLoadStrategy(), input.getFixedCourseIds())));
    }

    @Mutation
    @RolesAllowed(Permissions.PORTAL_SECTION_EDIT)
    @NotNull
    public boolean deletePortalSection(@NotNull @Valid DeletePortalSectionInput input) {
        return portalSectionService.editor().deleteById(input.getId());
    }
}
